package org.example.xsda.service;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.example.xsda.common.PageResult;
import org.example.xsda.entity.SysUser;
import org.example.xsda.exception.BusinessException;
import org.example.xsda.mapper.SysUserMapper;
import org.example.xsda.util.PasswordUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * 用户服务
 */
@Slf4j
@Service
public class UserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private RedisService redisService;

    // 缓存key前缀
    private static final String CACHE_KEY_USER = "user:";

    /**
     * 分页查询用户
     */
    public PageResult<SysUser> page(Long current, Long size, String keyword, Long roleId) {
        Page<SysUser> page = new Page<>(current, size);
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(keyword)) {
            wrapper.and(w -> w.like(SysUser::getUsername, keyword)
                    .or().like(SysUser::getRealName, keyword)
                    .or().like(SysUser::getPhone, keyword));
        }
        if (roleId != null) {
            wrapper.eq(SysUser::getRoleId, roleId);
        }
        wrapper.orderByDesc(SysUser::getCreateTime);
        
        Page<SysUser> userPage = sysUserMapper.selectPage(page, wrapper);
        // 清除密码字段
        userPage.getRecords().forEach(user -> user.setPassword(null));
        return new PageResult<>(userPage.getTotal(), userPage.getRecords(), userPage.getCurrent(), userPage.getSize());
    }

    /**
     * 根据ID获取用户（带缓存）
     */
    public SysUser getById(Long id) {
        String cacheKey = CACHE_KEY_USER + id;
        
        // 先从缓存中获取
        Object cached = redisService.get(cacheKey);
        if (cached != null) {
            log.debug("从缓存中获取用户信息：id={}", id);
            return (SysUser) cached;
        }
        
        // 缓存未命中，从数据库查询
        SysUser user = sysUserMapper.selectById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        user.setPassword(null);
        
        // 存入缓存（30分钟）
        redisService.set(cacheKey, user);
        log.debug("将用户信息存入缓存：id={}", id);
        
        return user;
    }

    /**
     * 新增用户
     */
    public void add(SysUser user) {
        // 检查用户名是否已存在
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getUsername, user.getUsername());
        Long count = sysUserMapper.selectCount(wrapper);
        if (count > 0) {
            throw new BusinessException("用户名已存在");
        }

        // 加密密码
        if (!StringUtils.hasText(user.getPassword())) {
            user.setPassword("123456"); // 默认密码
        }
        user.setPassword(PasswordUtil.encrypt(user.getPassword()));

        sysUserMapper.insert(user);
        
        // 清除用户列表缓存
        redisService.deleteByPattern(CACHE_KEY_USER);
        
        log.info("新增用户成功：{}", user.getUsername());
    }

    /**
     * 更新用户
     */
    public void update(SysUser user) {
        SysUser existUser = sysUserMapper.selectById(user.getId());
        if (existUser == null) {
            throw new BusinessException("用户不存在");
        }

        // 检查用户名是否重复
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getUsername, user.getUsername());
        wrapper.ne(SysUser::getId, user.getId());
        Long count = sysUserMapper.selectCount(wrapper);
        if (count > 0) {
            throw new BusinessException("用户名已存在");
        }

        // 如果密码为空，则不更新密码
        if (!StringUtils.hasText(user.getPassword())) {
            user.setPassword(null);
        } else {
            user.setPassword(PasswordUtil.encrypt(user.getPassword()));
        }

        sysUserMapper.updateById(user);
        
        // 清除缓存
        redisService.delete(CACHE_KEY_USER + user.getId());
        
        log.info("更新用户成功：{}", user.getUsername());
    }

    /**
     * 删除用户
     */
    public void delete(Long id) {
        SysUser user = sysUserMapper.selectById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        sysUserMapper.deleteById(id);
        
        // 清除缓存
        redisService.delete(CACHE_KEY_USER + id);
        
        log.info("删除用户成功：{}", user.getUsername());
    }

    /**
     * 重置密码
     */
    public void resetPassword(Long id) {
        SysUser user = sysUserMapper.selectById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        user.setPassword(PasswordUtil.encrypt("123456"));
        sysUserMapper.updateById(user);
        log.info("重置密码成功：{}", user.getUsername());
    }
    
    /**
     * 获取当前用户信息（带缓存）
     */
    public SysUser getProfile() {
        Long userId = StpUtil.getLoginIdAsLong();
        String cacheKey = CACHE_KEY_USER + userId;
        
        // 先从缓存中获取
        Object cached = redisService.get(cacheKey);
        if (cached != null) {
            log.debug("从缓存中获取当前用户信息：userId={}", userId);
            return (SysUser) cached;
        }
        
        // 缓存未命中，从数据库查询
        SysUser user = sysUserMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        // 清除密码字段
        user.setPassword(null);
        
        // 存入缓存（30分钟）
        redisService.set(cacheKey, user);
        log.debug("将当前用户信息存入缓存：userId={}", userId);
        
        return user;
    }
    
    /**
     * 更新当前用户信息
     * 只允许更新部分字段：头像、手机号、真实姓名
     */
    public void updateProfile(SysUser user) {
        Long userId = StpUtil.getLoginIdAsLong();
        SysUser existUser = sysUserMapper.selectById(userId);
        if (existUser == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 只更新允许的字段
        if (StringUtils.hasText(user.getAvatar())) {
            existUser.setAvatar(user.getAvatar());
        }
        if (StringUtils.hasText(user.getPhone())) {
            existUser.setPhone(user.getPhone());
        }
        if (StringUtils.hasText(user.getRealName())) {
            existUser.setRealName(user.getRealName());
        }
        
        sysUserMapper.updateById(existUser);
        
        // 清除缓存
        redisService.delete(CACHE_KEY_USER + userId);
        
        log.info("更新个人信息成功：userId={}", userId);
    }
    
    /**
     * 修改密码（首次登录或主动修改）
     */
    public void changePassword(String oldPassword, String newPassword) {
        Long userId = StpUtil.getLoginIdAsLong();
        SysUser user = sysUserMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 如果需要修改密码（首次登录），则不验证旧密码
        boolean isFirstLogin = user.getNeedChangePassword() != null && user.getNeedChangePassword() == 1;
        
        if (!isFirstLogin) {
            // 非首次登录，需要验证旧密码
            if (!StringUtils.hasText(oldPassword)) {
                throw new BusinessException("请输入原密码");
            }
            if (!PasswordUtil.verify(oldPassword, user.getPassword())) {
                throw new BusinessException("原密码错误");
            }
        }
        
        // 验证新密码
        if (!StringUtils.hasText(newPassword)) {
            throw new BusinessException("新密码不能为空");
        }
        if (newPassword.length() < 6) {
            throw new BusinessException("新密码长度不能少于6位");
        }
        
        // 更新密码并标记已修改
        user.setPassword(PasswordUtil.encrypt(newPassword));
        user.setNeedChangePassword(0);
        sysUserMapper.updateById(user);
        
        // 清除缓存
        redisService.delete(CACHE_KEY_USER + userId);
        
        log.info("修改密码成功：userId={}, isFirstLogin={}", userId, isFirstLogin);
    }
}

